package trip

import (
	"gitee.com/sweetsunnyflower/carpooling-server-go/pkg/app"
	"gitee.com/sweetsunnyflower/carpooling-server-go/pkg/database"
	"gitee.com/sweetsunnyflower/carpooling-server-go/pkg/paginator"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"

	"github.com/gofiber/fiber/v2"
)

func Get(id uint64) (trip Trip) {
	database.DB.Where("id", id).Preload("TripRider").First(&trip)
	return
}

func GetTripByIdWithAll(id uint64, userId uint64) (trip QueryTrip) {
	database.DB.Table("trips").Preload("User").Preload("TripRider", func(db *gorm.DB) *gorm.DB {
		if userId == 0 {
			return db.Select("*")
		} else {
			return db.Where("user_id = ?", userId).Select("*")
		}
	}).Preload("BeFollow", func(db *gorm.DB) *gorm.DB {
		if userId == 0 {
			return db.Select("*")
		} else {
			return db.Where("user_id = ?", userId).Select("*")
		}
	}).Preload("Driver", func(db *gorm.DB) *gorm.DB {
		return db.Preload(clause.Associations).Select("*")
	}).Preload("From").Preload("To").Preload("Vehicle", func(db *gorm.DB) *gorm.DB {
		return db.Preload(clause.Associations).Select("*")
	}).Where("id", id).First(&trip)
	return
}

func GetTripsCountByUserId(userId uint64) (count int64) {
	database.DB.Model(Trip{}).Where("user_id", userId).Count(&count)
	return
}

func GetTripsByIdWithAll(querys map[string]string, userId uint64) (trips []QueryTrip) {
	tripModel := database.DB.Table("trips").Preload("User").Preload("TripRider", func(db *gorm.DB) *gorm.DB {
		if userId == 0 {
			return db.Select("*")
		} else {
			return db.Where("user_id = ?", userId).Select("*")
		}
	}).Preload("BeFollow", func(db *gorm.DB) *gorm.DB {
		if userId == 0 {
			return db.Select("*")
		} else {
			return db.Where("user_id = ?", userId).Select("*")
		}
	}).Preload("Driver", func(db *gorm.DB) *gorm.DB {
		return db.Preload(clause.Associations).Select("*")
	}).Preload("From").Preload("To").Preload("Vehicle", func(db *gorm.DB) *gorm.DB {
		return db.Preload(clause.Associations).Select("*")
	}).Order("id desc")

	if value, ok := querys["user_id"]; ok {
		tripModel.Where("user_id = ?", value)
	}

	if value, ok := querys["id"]; ok {
		tripModel.Where("id < ?", value)
	}

	// 起点
	if value, ok := querys["from_id"]; ok {
		tripModel.Where("start_location = ?", value)
	}

	// 终点
	if value, ok := querys["to_id"]; ok {
		tripModel.Where("end_location = ?", value)
	}

	// 起始时间
	if value, ok := querys["start_time"]; ok {
		tripModel.Where("departure_time >= ?", value)
	}

	// 终止时间
	if value, ok := querys["end_time"]; ok {
		tripModel.Where("departure_time < ?", value)
	}

	tripModel.Limit(10).Find(&trips)

	return
}

func GetUserLatestTrip(userId uint64) (trip Trip) {
	database.DB.Where("user_id = ?", userId).Order("id desc").First(&trip)
	return
}

func GetBy(field, value string) (trip Trip) {
	database.DB.Where("? = ?", field, value).First(&trip)
	return
}

func All() (trips []Trip) {
	database.DB.Order("id desc").Find(&trips)
	return
}

func IsExist(field, value string) bool {
	var count int64
	database.DB.Model(Trip{}).Where("? = ?", field, value).Count(&count)
	return count > 0
}

// Paginate 分页内容
func Paginate(c *fiber.Ctx, perPage int) (trips []Trip, paging paginator.Paging) {
	paging = paginator.Paginate(
		c,
		database.DB.Model(Trip{}),
		&trips,
		app.V1URL(database.TableName(&Trip{})),
		perPage,
	)
	return
}
